package com.lonely.goods.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetPartProcessDTO;
import com.lonely.goods.domain.entity.SysGoodsProcessItem;
import com.lonely.goods.mapper.SysGoodsProcessItemMapper;
import com.lonely.goods.service.IGoodsProcessItemService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 商品工序明细服务实现类
 *
 * @author fzzf
 */
@Service
public class GoodsProcessItemServiceImpl extends ServiceImpl<SysGoodsProcessItemMapper, SysGoodsProcessItem> implements IGoodsProcessItemService {

    /**
     * 更新工序明细数据
     *
     * @param goodsProcessId
     * @param processItems
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitGoodsProcessItems(Long goodsProcessId, List<GoodsQuotationSheetPartProcessDTO.ProcessItemVO> processItems) {

        // 获取数据库中当前工序对应的工序明细数据
        List<SysGoodsProcessItem> existsGoodsProcessItems = super.list(new LambdaQueryWrapper<SysGoodsProcessItem>()
                .eq(SysGoodsProcessItem::getGoodsProcessId, goodsProcessId)
        );
        List<Long> existsGoodsProcessItemIds = existsGoodsProcessItems.stream().map(BaseEntity::getId).filter(Objects::nonNull).collect(Collectors.toList());

        // 提交的工艺明细数据
        List<GoodsQuotationSheetPartProcessDTO.ProcessItemVO> submitProcessItems = Optional.ofNullable(processItems).orElse(new ArrayList<>());
        List<Long> submitGoodsProcessItemIds = submitProcessItems.stream().map(GoodsQuotationSheetPartProcessDTO.ProcessItemVO::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());


        // 找到待新增的数据
        List<GoodsQuotationSheetPartProcessDTO.ProcessItemVO> needAddGoodsProcessItemList = submitProcessItems.stream().filter(x -> x.getId() == null).collect(Collectors.toList());

        // 找到待删除的数据
        List<Long> needRemoveGoodsProcessItemIds = existsGoodsProcessItemIds.stream().filter(x -> !submitGoodsProcessItemIds.contains(x)).distinct().collect(Collectors.toList());

        // 找到待更新的数据
        List<Long> needUpdateGoodsProcessItemIds = existsGoodsProcessItemIds.stream().filter(submitGoodsProcessItemIds::contains).distinct().collect(Collectors.toList());


        if (CollUtil.isNotEmpty(needAddGoodsProcessItemList)) {
            List<SysGoodsProcessItem> needAddGspList = needAddGoodsProcessItemList.stream().map(x -> {
                SysGoodsProcessItem sysGoodsProcessItem = new SysGoodsProcessItem();
                BeanUtils.copyProperties(x, sysGoodsProcessItem);
                sysGoodsProcessItem.setGoodsProcessId(goodsProcessId);
                sysGoodsProcessItem.setProcessName(x.getProcessName());
                sysGoodsProcessItem.setWage(x.getWage());
                sysGoodsProcessItem.setCreateBy(SecurityUtils.getUserId());
                sysGoodsProcessItem.setUpdateBy(SecurityUtils.getUserId());
                return sysGoodsProcessItem;
            }).collect(Collectors.toList());

            super.saveBatch(needAddGspList);
        }

        if (CollUtil.isNotEmpty(needRemoveGoodsProcessItemIds)) {
            super.removeByIds(needRemoveGoodsProcessItemIds);
        }

        if (CollUtil.isNotEmpty(needUpdateGoodsProcessItemIds)) {
            Map<Long, GoodsQuotationSheetPartProcessDTO.ProcessItemVO> submitGoodsProcessMap = submitProcessItems.stream().filter(x -> needUpdateGoodsProcessItemIds.contains(x.getId()))
                    .collect(Collectors.toMap(GoodsQuotationSheetPartProcessDTO.ProcessItemVO::getId, Function.identity(), (a, b) -> b));
            List<SysGoodsProcessItem> needUpdateGoodsProcessModels = existsGoodsProcessItems.stream().filter(x -> needUpdateGoodsProcessItemIds.contains(x.getId()))
                    .peek(x -> {
                        GoodsQuotationSheetPartProcessDTO.ProcessItemVO processItemVO = submitGoodsProcessMap.get(x.getId());
                        BeanUtils.copyProperties(processItemVO, x);
                    }).collect(Collectors.toList());
            super.updateBatchById(needUpdateGoodsProcessModels);
        }


    }
}
